import FormDateRangePicker from "./DateRangePicker";
import FormInput from "./Input";
import FormSelect from "./Select";
import FormCheckbox from "./Checkbox";
import FormSwitch from "./Switch";
import Button from "ant-design-vue/es/button";
import Form from "ant-design-vue/es/form";
import Table from "ant-design-vue/es/table";
import Icon from "ant-design-vue/es/icon";
import DropDown from "ant-design-vue/es/dropdown";
import Tag from "ant-design-vue/es/tag";
import "ant-design-vue/lib/tag/style/css";
import "ant-design-vue/lib/dropdown/style/css";
import "ant-design-vue/lib/icon/style/css";
import "ant-design-vue/lib/form/style/css";
import "ant-design-vue/lib/button/style/css";
import "ant-design-vue/lib/table/style/css";
import "./dropDownPanel.less";
import { getObj } from "../util/util";
const { Item } = Form;
import cloneDeep from "lodash/cloneDeep";
export default {
  name: "DropDownPanel",
  components: {
    FormDateRangePicker,
    FormInput,
    FormSelect,
    FormCheckbox,
    FormSwitch
  },
  props: {
    option: {
      type: Object,
      default() {
        return {};
      }
    },
    value: [Number, String, Array]
  },
  model: {
    prop: "value",
    event: "updata"
  },
  watch: {
    params() {
      this.paginationOption.PageIndex = 0;
      this.paginationOption.current = 1;
      this.fetch();
    },
    currentValue(val) {
      if (this.gridOption.valueKey) {
        const rows = this.getSelecteds();
        const data = rows.map(v => {
          return v[this.gridOption.valueKey];
        });
        this.$emit("updata", data);
        this.$emit("change", data);
      } else {
        this.$emit("updata", val);
        this.$emit("change", val);
      }
    }
  },
  data() {
    return {
      form: this.$form.createForm(this),
      visible: false,
      originValue: "",
      paginationOption: {},
      selectedRowKeys: [],
      selectedRows: [],
      gridSelectedRow: "",
      selectGridIds: [],
      showField: "",
      rowKey: "Id",
      searchForm: [],
      PageIndex: 0,
      PageSize: 10,
      gridData: [],
      loading: false,
      currentValue: ""
    };
  },
  computed: {
    contentOption() {
      return this.option.content ? this.option.content : {};
    },
    searchOption() {
      return this.contentOption && this.contentOption.search
        ? this.contentOption.search
        : {};
    },
    gridOption() {
      return this.contentOption && this.contentOption.grid
        ? this.contentOption.grid
        : null;
    },
    api() {
      return this.contentOption && this.contentOption.grid
        ? this.contentOption.grid.api
        : null;
    },
    params() {
      return this.gridOption && this.gridOption.params
        ? this.gridOption.params
        : {};
    },
    dataField() {
      return this.gridOption && this.gridOption.dataField
        ? this.gridOption.dataField
        : "Data.Datas";
    },
    totalField() {
      return this.gridOption && this.gridOption.totalField
        ? this.gridOption.totalField
        : "Data.Total";
    }
  },
  created() {
    this.originValue = cloneDeep(this.value);
    this.currentValue = this.value;
    this.searchForm = this.searchOption.form;
    //表格数据默认参数
    if (this.gridOption) {
      if (this.api) {
        this.fetch(); //获取数据
      }
      const basePaginationOption = {
        showSizeChanger: true,
        showQuickJumper: true,
        PageIndex: this.PageIndex,
        PageSize: this.PageSize
      };
      this.paginationOption = {
        ...basePaginationOption,
        ...this.gridOption.pagination
      };
      this.showField = this.gridOption.labelKey
        ? this.gridOption.labelKey
        : "Text";
      this.rowKey = this.gridOption.rowKey ? this.gridOption.rowKey : "Id";
      this.selectGridIds = this.gridOption.selectedIds
        ? this.gridOption.selectedIds
        : [];
      this.setSelecteds(this.selectGridIds);
      this.gridData = this.gridOption.data ? this.gridOption.data : [];
    }
  },
  methods: {
    // 生成搜索表单
    getSearchFormContent(h) {
      let itemIndex = 0;
      if (!this.searchForm || !this.searchForm.length) {
        return false;
      }
      let content = this.searchForm.map(item => {
        const _index = itemIndex;
        itemIndex++;
        let inputNode = "";
        if (item.type === null) {
          return <div class="data-form-item "> </div>;
        } else if (item.slot && this.$slots[item.slot]) {
          inputNode = this.$slots[item.slot];
        } else if (item.slot && this.$scopedSlots[item.slot]) {
          inputNode = this.$scopedSlots[item.slot];
        } else {
          inputNode = this.getInputNode(item, _index, h);
        }
        let itemStyle = {};
        const isColon = item.colon === false || !item.label ? false : true;

        let label = "";
        if (item.label !== false) {
          //标题内容
          let labelText = "";
          if (typeof item.label === "function") {
            labelText = [item.label()];
          } else {
            labelText = item.label;
          }
          label = h(
            "div",
            {
              class: ["data-form-item-label", { colon: isColon }]
            },
            labelText
          );
        }
        if (item.width) {
          itemStyle["width"] =
            typeof item.width === "number" ? item.width + "px" : item.width;
        }
        const itemOption = {
          props: {
            colon: isColon,
            extra: item.extra
          },
          class: "data-form-item"
        };
        return (
          <Item {...itemOption}>
            <div class="data-form-item-wrapper">
              {label}
              <div class="data-form-item-content" style={itemStyle}>
                {inputNode}
              </div>
            </div>
          </Item>
        );
      });
      const searchButton = h(
        Button,
        {
          props: {
            type: "primary"
          },
          on: {
            click: () => {
              this.onSearch();
            }
          }
        },
        "查询"
      );
      const formOption = {
        props: {
          form: this.form,
          layout: "inline"
        }
      };
      return (
        <Form {...formOption}>
          {content}
          <Item>{searchButton}</Item>
        </Form>
      );
    },
    // 搜索事件
    onSearch() {
      this.$nextTick(() => {
        const values = this.form.getFieldsValue();
        const json = {};
        Object.keys(values).forEach(item => {
          if (values[item] != undefined) {
            json[item] = values[item];
          }
        });
        console.log("搜索参数", json);
        if (this.searchOption.onSearchBefore) {
          let callbackRes = this.searchOption.onSearchBefore(json);
          if (callbackRes === false) {
            return;
          } else if (callbackRes) {
            this.fetch(callbackRes);
          }
        } else {
          this.fetch(json);
        }
      });
    },
    fetch(params = {}) {
      const baseParams = {
        PageSize: this.PageSize,
        PageIndex: this.PageIndex
      };
      const json = { ...baseParams, ...this.params, ...params };
      this.PageSize = json.PageSize;
      console.log("params……", json);
      if (this.api) {
        this.loading = true;
        this.api(json)
          .then(res => {
            console.log("loading data……");
            const pagination = { ...this.paginationOption };
            const data = getObj(this.dataField, res);
            const total = getObj(this.totalField, res);
            pagination.total = total;
            pagination.PageSize = this.PageSize;
            pagination.current = json.PageIndex + 1;
            this.loading = false;
            this.paginationOption = pagination;
            this.gridData = data;
          })
          .catch(err => {
            console.log(err);
            this.loading = false;
          });
      }
    },
    //生成表格内容
    getGridContent() {
      const gridProps = {
        ...this.gridOption.props,
        columns: this.gridOption.columns,
        pagination: this.paginationOption,
        rowKey: this.rowKey,
        dataSource: this.gridData,
        loading: this.loading,
        customRow: record => {
          return {
            on: {
              // 点击行
              click: e => {
                this.$emit("rowclick", e);
                if (!this.gridOption.rowSelect) {
                  this.onSelectedRow(record);
                }
              }
            }
          };
        },
        rowClassName: record => {
          return (this.gridSelectedRow[this.rowKey] &&
            record[this.rowKey] === this.gridSelectedRow[this.rowKey]) ||
            this.selectedRowKeys.includes(record[this.rowKey])
            ? "active"
            : "";
        }
      };
      //是否显示多选或者单选控件
      if (this.gridOption.rowSelect) {
        gridProps.rowSelection = {
          selectedRowKeys: this.selectedRowKeys,
          type: this.gridOption.rowSelect === "radio" ? "radio" : "checkbox",
          onChange: (selectedRowKeys, selectedRows) => {
            this.onSelectGridChange(selectedRowKeys, selectedRows);
          },
          onSelect: (record, selected, selectedRows) => {
            this.$emit("rowclick", selected);
            this.selectedRows = selectedRows;
            this.$emit("select", record);
          },
          onSelectAll: (selected, selectedRows) => {
            this.selectedRows = selectedRows;
          }
        };
      }
      let gridScopedSlots = this.$scopedSlots;
      const dataGridProps = {
        ref: "dataGrid",
        props: gridProps,
        on: {
          change: (pagination, filters, sorter) => {
            this.handleTableChange(pagination, filters, sorter);
          }
        },
        scopedSlots: gridScopedSlots
      };
      return <Table {...dataGridProps}></Table>;
    },
    //无单选或多选控件时选择行事件
    onSelectedRow(row) {
      this.$emit("beforeselect", this.gridSelectedRow);
      if (this.gridSelectedRow[this.rowKey] === row[this.rowKey]) {
        this.gridSelectedRow = "";
      } else {
        this.gridSelectedRow = row;
      }
      this.currentValue = row[this.showField];
      this.$emit("select", this.gridSelectedRow);
      this.$emit(
        "afterselect",
        this.gridSelectedRow[this.rowKey],
        this.gridSelectedRow
      );
    },
    // 单选或多选控件选择时触发事件
    onSelectGridChange(selectedRowKeys, selectedRows) {
      this.$emit("beforeselect", this.selectedRows);
      this.selectedRowKeys = selectedRowKeys;
      const result = selectedRows.map(v => {
        return v[this.showField];
      });
      if (this.option.props && this.option.props.delete) {
        this.currentValue = result;
      } else {
        const sep =
          this.option.props && this.option.props.separateIcon
            ? this.option.props.separateIcon
            : ",";
        const selVal = result.join(sep);
        this.currentValue = selVal;
      }
      this.$emit("afterselect", selectedRowKeys, selectedRows);
    },
    // 翻页
    handleTableChange(pagination, filters, sorter) {
      console.log("sorter", sorter);
      const pager = { ...this.paginationOption };
      pager.PageIndex = pagination.current - 1;
      pager.current = pagination.current;
      pager.PageSize = pagination.pageSize;
      pager.pageSize = pagination.pageSize;
      this.paginationOption = pager;
      let json = {
        PageSize: pager.PageSize,
        PageIndex: pager.PageIndex,
        ...filters
      };
      this.fetch(json);
    },
    //设置多选选中行数据
    setSelecteds(keys) {
      this.selectedRowKeys = keys;
    },
    //获取选中行
    getSelected() {
      return this.gridSelectedRow;
    },
    //获取多选中行
    getSelecteds() {
      return this.selectedRows;
    },
    //删除选中项
    closeTag(e, index) {
      e.stopPropagation();
      e.preventDefault();
      const vals = cloneDeep(this.currentValue);
      vals.splice(index, 1);
      this.selectedRowKeys.splice(index, 1);
      this.currentValue = vals;
    },
    //触发面板内容
    getDropLinkContent() {
      const props = this.option.props;
      const dropProps = props ? props.options : {};
      let w = "100%";
      if (props && props.width) {
        w = typeof props.width === "number" ? props.width + "px" : props.width;
      }
      const dropLinkProps = {
        props: {
          ...dropProps,
          readonly: true
        },
        style: {
          width: w
        },
        class: {
          "drop-link": true
        }
      };
      let tags = [];
      if (props && props.delete) {
        dropLinkProps.class["drop-tags"] = true;
        if (typeof this.currentValue == "object" && this.currentValue.length) {
          this.currentValue.forEach((el, index) => {
            const closeTag = {
              close: e => {
                this.closeTag(e, index);
              }
            };
            tags.push(
              <Tag key={index} value={el} closable {...{ on: closeTag }}>
                {el}
              </Tag>
            );
          });
        } else {
          tags = [this.currentValue];
        }
        return (
          <div ref="dropLink" {...dropLinkProps}>
            <div class="tags">{tags}</div>
            <Icon {...{ props: { type: "down" } }}></Icon>
          </div>
        );
      }
      return (
        <div ref="dropLink" {...dropLinkProps}>
          <FormInput readonly={true} value={this.currentValue}></FormInput>
          <Icon {...{ props: { type: "down" } }}></Icon>
        </div>
      );
    },
    //下拉面板状态改变事件
    visibleChange(visible) {
      this.visible = visible;
      if (visible) {
        this.originValue = cloneDeep(this.currentValue);
        if (this.gridOption) {
          this.selectGridIds = this.selectedRowKeys;
          this.setSelecteds(this.selectGridIds);
        }
        if (this.searchForm && this.searchForm.length) {
          this.$nextTick(() => {
            this.form.resetFields();
          });
        }
        this.$emit("open");
      }
    },
    //清除
    handleClear() {
      if (this.option.props && this.option.props.delete) {
        this.currentValue = [];
      } else {
        this.currentValue = "";
      }
      this.$emit("clear");
      if (this.gridOption) {
        this.setSelecteds([]);
        this.selectGridIds = [];
        this.gridSelectedRow = "";
      }
    },
    //取消
    handleCancel() {
      if (this.gridOption) {
        this.setSelecteds(this.selectGridIds);
      }
      this.currentValue = cloneDeep(this.originValue);
      this.$emit("cancel", this.originValue);
      this.handleClose();
    },
    //确定
    handleOk() {
      this.$emit("onSubmit", this.currentValue);
      this.handleClose();
    },
    handleClose() {
      this.$emit("close", this.currentValue);
      this.visible = false;
      this.$emit("destory");
    },
    //生成页脚内容
    getFooterAction() {
      const buttonProps = {
        props: {
          type: "primary",
          size: "small"
        }
      };
      const onClear = {
        click: () => {
          this.handleClear();
        }
      };
      const onCancel = {
        click: () => {
          this.handleCancel();
        }
      };
      const onOk = {
        click: () => {
          this.handleOk();
        }
      };
      const footer = (
        <div>
          <Button {...{ on: onClear }} style="float:left" {...buttonProps}>
            清除
          </Button>
          <Button {...{ on: onCancel }} {...buttonProps}>
            取消
          </Button>
          <Button {...{ on: onOk }} {...buttonProps}>
            确定
          </Button>
        </div>
      );
      return footer;
    },
    // 生成输入元素
    getInputNode(node, index, h) {
      const inputs = {
        input: "FormInput",
        select: "FormSelect",
        dateRange: "FormDateRangePicker",
        checkbox: "FormCheckbox",
        switch: "FormSwitch"
      };

      const vDecorator = [node.name];
      if (node.option) {
        vDecorator.push(node.option);
      }
      const nodeProps = node.props ? node.props : {};

      const props = {
        ref: "input_" + index,
        props: {
          ...nodeProps,
          placeholder: node.placeholder,
          option: node
        },
        on: {
          ...node.on
        },
        directives: [
          {
            name: "decorator",
            value: vDecorator
          }
        ]
      };
      const type = node.type ? node.type : "input";
      const inputName = inputs[type];
      const input = h(inputName, props);
      return input;
    }
  },
  render(h) {
    const dropContent = this.getDropLinkContent();
    //搜索表单
    let searchContent = this.contentOption.searchForm
      ? this.contentOption.searchForm
      : "";
    if (this.searchForm && this.searchForm.length) {
      searchContent = this.getSearchFormContent(h);
    }
    //主要内容
    let content = this.contentOption.contentData
      ? this.contentOption.contentData
      : "";
    if (this.gridOption && !content) {
      content = this.getGridContent();
    }
    const contentStyle = {},
      contentWidth = this.contentOption.width;
    if (contentWidth) {
      contentStyle["width"] =
        typeof contentWidth === "number" ? contentWidth + "px" : contentWidth;
    }
    let footer = this.contentOption.footerAction
      ? this.contentOption.footerAction
      : "";
    if (!footer) {
      footer = this.getFooterAction();
    }
    const onClose = {
      click: () => {
        this.handleClose();
      }
    };
    let overlayContent = this.$slots.default;

    const title = this.contentOption.title ? this.contentOption.title : "标题";
    overlayContent = (
      <div
        slot="overlay"
        ref="overlay"
        class="overlay-box"
        style={contentStyle}
      >
        <div class="overlay-title">
          {title}
          <span class="close" {...{ on: onClose }}>
            <Icon type="close" />
          </span>
        </div>
        <div class="overlay-content">
          <div class="data-form-box">{searchContent}</div>
          <div class="data-content"> {content}</div>
        </div>
        <div class="overlay-footer">{footer}</div>
      </div>
    );

    const dropDownProps = {
      props: {
        visible: this.visible,
        ...this.option.props
      },
      on: {
        visibleChange: e => {
          this.visibleChange(e);
        }
      }
    };
    return (
      <DropDown class="drop-down-box" {...dropDownProps}>
        {dropContent}
        {overlayContent}
      </DropDown>
    );
  }
};
